Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Field3D::setBoundaryTo parallel boundary conditions #2962

Open
wants to merge 8 commits into
base: next
Choose a base branch
from

Conversation

bendudson
Copy link
Contributor

Didn't handle parallel boundaries correctly. Now handles input arguments with and without parallelslices. If the input doesn't have parallel slices then they should be cleared in the target field, and to/fromFieldAligned used to set Y boundaries in field-aligned coordinates.

See discussion here of issue caused by previous implementation: bendudson/hermes-3@97a21fd

Didn't handle parallel boundaries correctly. Now handles input arguments
with and without parallelslices. If the input doesn't have parallel slices
then they should be cleared in the target field, and to/fromFieldAligned
used to set Y boundaries in field-aligned coordinates.
bendudson referenced this pull request in bendudson/hermes-3 Aug 17, 2024
Must clear P parallel slices or Grad_par will use them.
Alternatively, setBoundaryTo should clear the parallel slices
if they are not set in the argument.
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

src/field/field3d.cxx Outdated Show resolved Hide resolved
src/field/field3d.cxx Outdated Show resolved Hide resolved
ASSERT1(hasParallelSlices());

for (auto& bndry : fieldmesh->getBoundariesPar()) {
const Field3D& f3d_next = f3d.ynext(bndry->dir);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no member named 'x' in 'BoundaryRegionPar' [clang-diagnostic-error]

        const int x = bndry->x;
                             ^


for (auto& bndry : fieldmesh->getBoundariesPar()) {
const Field3D& f3d_next = f3d.ynext(bndry->dir);
Field3D& this_next = ynext(bndry->dir);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no member named 'y' in 'BoundaryRegionPar' [clang-diagnostic-error]

        const int y = bndry->y;
                             ^

for (auto& bndry : fieldmesh->getBoundariesPar()) {
const Field3D& f3d_next = f3d.ynext(bndry->dir);
Field3D& this_next = ynext(bndry->dir);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no member named 'z' in 'BoundaryRegionPar' [clang-diagnostic-error]

        const int z = bndry->z;
                             ^

clearParallelSlices();

// Shift into field-aligned coordinates to apply Y boundary conditions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: loop variable name 'r' is too short, expected at least 2 characters [readability-identifier-length]

    for (RangeIterator r = fieldmesh->iterateBndryLowerY(); !r.isDone(); r++) {
                       ^

src/field/field3d.cxx Outdated Show resolved Hide resolved
for (RangeIterator r = fieldmesh->iterateBndryLowerY(); !r.isDone(); r++) {
for (int jz = 0; jz < fieldmesh->LocalNz; jz++) {
BoutReal val = 0.5
* (f3d_fa(r.ind, fieldmesh->ystart, jz)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: loop variable name 'r' is too short, expected at least 2 characters [readability-identifier-length]

    for (RangeIterator r = fieldmesh->iterateBndryUpperY(); !r.isDone(); r++) {
                       ^

BoutReal val = 0.5
* (f3d_fa(r.ind, fieldmesh->ystart, jz)
+ f3d_fa(r.ind, fieldmesh->ystart - 1, jz));
(*this)(r.ind, fieldmesh->ystart - 1, jz) =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'val' of type 'BoutReal' (aka 'double') can be declared 'const' [misc-const-correctness]

Suggested change
(*this)(r.ind, fieldmesh->ystart - 1, jz) =
BoutReal const val = 0.5 * (f3d_fa(r.ind, fieldmesh->yend, jz) + f3d_fa(r.ind, fieldmesh->yend + 1, jz));

@bendudson bendudson added the work in progress Not ready for merging label Aug 17, 2024
Copy link
Contributor

@dschwoerer dschwoerer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the yboundary iterator had changed, but if it compiles it seems that has not yet been merged.

On a more general question, what is the purpose of this function? I do understand what it does, but why would one want to use it? Why not simply copy the boundaries? In what cases is this useful?

src/field/field3d.cxx Outdated Show resolved Hide resolved
src/field/field3d.cxx Outdated Show resolved Hide resolved
Comment on lines 484 to 495
for (auto& bndry : fieldmesh->getBoundariesPar()) {
const Field3D& f3d_next = f3d.ynext(bndry->dir);
Field3D& this_next = ynext(bndry->dir);

for (bndry->first(); !bndry->isDone(); bndry->next()) {
const int x = bndry->x;
const int y = bndry->y;
const int z = bndry->z;
BoutReal val = 0.5 * (f3d(x, y, z) + f3d_next(x, y, z));
this_next(x, y, z) = 2. * val - (*this)(x, y, z);
}
}
Copy link
Contributor

@dschwoerer dschwoerer Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be roughly the new syntax:

Suggested change
for (auto& bndry : fieldmesh->getBoundariesPar()) {
const Field3D& f3d_next = f3d.ynext(bndry->dir);
Field3D& this_next = ynext(bndry->dir);
for (bndry->first(); !bndry->isDone(); bndry->next()) {
const int x = bndry->x;
const int y = bndry->y;
const int z = bndry->z;
BoutReal val = 0.5 * (f3d(x, y, z) + f3d_next(x, y, z));
this_next(x, y, z) = 2. * val - (*this)(x, y, z);
}
}
for (auto& region : fieldmesh->getBoundariesPar()) {
for (auto& pnt: region) {
pnt.dirichlet_o1(*this, pnt.interpolate_sheath_o1(f3d));
}
}

bendudson and others added 6 commits August 19, 2024 08:36
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

for (int jy = fieldmesh->ystart; jy <= fieldmesh->yend; ++jy) {
for (int jz = 0; jz < fieldmesh->LocalNz; jz++) {
BoutReal const val =
0.5 * (f3d(fieldmesh->xstart, jy, jz) + f3d(fieldmesh->xstart - 1, jy, jz));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: expression result unused [clang-diagnostic-unused-value]

              0.5 * (f3d(fieldmesh->xstart, jy, jz) + f3d(fieldmesh->xstart - 1, jy, jz));
                  ^

}
}
}
if (fieldmesh->lastX()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'jy' [clang-diagnostic-error]

          BoutReal const val = 0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
                                                           ^

}
}
}
if (fieldmesh->lastX()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'jz' [clang-diagnostic-error]

          BoutReal const val = 0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
                                                               ^

}
}
}
if (fieldmesh->lastX()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'jy' [clang-diagnostic-error]

          BoutReal const val = 0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
                                                                                              ^

}
}
}
if (fieldmesh->lastX()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'jz' [clang-diagnostic-error]

          BoutReal const val = 0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
                                                                                                  ^

if (fieldmesh->lastX()) {
BoutReal const val =
0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
for (int jz = 0; jz < fieldmesh->LocalNz; jz++) {
BoutReal val =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'jy' [clang-diagnostic-error]

          (*this)(fieldmesh->xend + 1, jy, jz) =
                                       ^

// Set to this value
(*this)(reg->x, reg->y, z) =
2. * val - (*this)(reg->x - reg->bx, reg->y - reg->by, z);
0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'jy' [clang-diagnostic-error]

              2. * val - (*this)(fieldmesh->xend, jy, jz);
                                                  ^

}
}
}
}

// Y boundaries
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: expected unqualified-id [clang-diagnostic-error]

  if (f3d.hasParallelSlices()) {
  ^

BoutReal val = 0.5 * (f3d(x, y, z) + f3d_next(x, y + bndr->dir, z));
this_next(x, y + bndry->dir, z) = 2. * val - (*this)(x, y, z);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: expected unqualified-id [clang-diagnostic-error]

  } else {
    ^

(*this)(r.ind, fieldmesh->yend + 1, jz) =
2. * val - (*this)(r.ind, fieldmesh->yend, jz);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: extraneous closing brace ('}') [clang-diagnostic-error]

}
^

@bendudson
Copy link
Contributor Author

Thanks @dschwoerer ! What is being done is:

  • A field (P) comes from the solver
  • It is modified, removing negative values and handling low density regions
  • The modified field has a boundary condition applied
  • The original field now should be modified to have the same boundary condition as the modified field.

One option is to just copy the boundary cells, but then the boundary condition would be slightly different. I'm not sure which would be better behaved numerically.

@dschwoerer
Copy link
Contributor

I see, so the assumption is that both fields are very similar.
One thing that could happen with this method, if you want to ensure positive also of the boundary cells, and you modify them in this operation, you lose that property, and there is no way around this. Also note that this only copies Dirichlet boundary conditions, that should probably be documented.

I have pushed a fix, either as an additional commit (https://github.com/boutproject/BOUT-dev/tree/fix-setboundaryto-fixup) or squashed to remove the broken commits from history, for easier bisecting in the future (https://github.com/boutproject/BOUT-dev/tree/fix-setboundaryto-rebase)

@dschwoerer
Copy link
Contributor

One test is failing as it triggers the assertion about parallel slices:

26/50 Test #28: test-invertable-operator ............***Failed    4.89 sec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix work in progress Not ready for merging
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants